﻿using System;
using System.Linq;
using System.Reflection;

namespace Keede.RabbitMQ.EasyClient
{
    public abstract class BaseClient : IDisposable
    {
        protected Client _mqClient;
        public Client MqClient => _mqClient;

        protected string _exchange;
        private bool _alreadyDispose;
        readonly string _msgAssembly;

        protected BaseClient(Authorization auth, string exchange, string msgAssembly, bool isLogDetail = false, ushort prefetchCount = 20)
        {
            this._exchange = exchange;
            this._msgAssembly = msgAssembly;
            this._mqClient = new Client(auth, isLogDetail, prefetchCount);
            this.Initialize();
        }


        protected BaseClient(Authorization auth, string exchange, bool isLogDetail = false)
        {
            this._exchange = exchange;
            this._mqClient = new Client(auth, isLogDetail);
        }

        private void Initialize()
        {
            this._mqClient.ExchangeDeclare(this._exchange, ExchangeType.Direct);
            var types = Assembly.Load(_msgAssembly).GetTypes().Where(w => w.IsSubclassOf(typeof(BaseMsg)));
            foreach (var type in types)
            {
                this._mqClient.QueueDeclare(queue: type.Name);
                this._mqClient.QueueBind(exchange: this._exchange, queue: type.Name, routingKey: type.Name);
            }
        }

        #region dispose
        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize((object)this);
        }

        ~BaseClient()
        {
            this.Dispose(true);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (this._alreadyDispose)
                return;
            if (disposing)
            {
                this._mqClient.Dispose();
            }
            this._alreadyDispose = true;
        }
        #endregion
    }
}
